﻿using System;
using System.Linq;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using Pharmacy;
using Pharmacy.Entities;
using VCS.Data;
using VCS.Entities;
using VCS.Settings.BusinessLayer;
using VCS.Windows.Forms.Properties;

namespace VCS.Windows.Forms.Form.Main
{
    /// <summary>
    /// </summary>
    public partial class FormInvoice : XtraForm
    {
        private Entities.TList<InvoiceDetails> listDetails;
        private PatientActivation patientActivation;
        private InvoiceDetails editItem;
        /// <summary>
        /// 	Form Prescription
        /// </summary>
        public FormInvoice()
        {
            InitializeComponent();
            LoadDefault();
        }

        /// <summary>
        /// </summary>
        public TextBox TextBoxTransactionID
        {
            get { return tb_TransactionID; }
            set { tb_TransactionID = value; }
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            switch (keyData)
            {
                case Keys.F1:
                    tb_TransactionID.Focus();
                    return true;
                case Keys.F2:
                    customGridLookUpEdit1.Focus();
                    return true;
                case Keys.F3:
                    cgle_PaymentMode.Focus();
                    return true;
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }

        private void LoadDefault()
        {
            tb_TransactionID.Text = "26FEB13HCM1-003";
            ServiceFacade.SettingsHelper.VATPercent = 0;
            var medicalProcedures = DataRepository.MedicalProcedureProvider.GetAll();
            DataRepository.MedicalProcedureProvider.DeepLoad(medicalProcedures, true);
            customGridLookUpEdit1.Properties.DisplayMember = "ProcedureDescription";
            customGridLookUpEdit1.Properties.DataSource = medicalProcedures;
            customGridLookUpEdit1.Enter += customGridLookUpEdit1_Enter;

            clnAmountPrice.DisplayFormat.FormatString = Resources.NumberFormat;
            clnUnitPrice.DisplayFormat.FormatString = Resources.NumberFormat;

            listDetails = new Entities.TList<InvoiceDetails>();
            gridControl1.DataSource = listDetails;

            var paymentModes = DataRepository.PaymentModeProvider.GetAll();
            cgle_PaymentMode.Properties.DisplayMember = "AccountName";
            cgle_PaymentMode.Properties.DataSource = paymentModes;

            int count;
            var drs = DataRepository.AppointmentDoctorProvider.GetPaged("UserGroupId='Doctor'", "DisplayName", 0, 1000, out count);
            cgle_DrCode.Properties.DisplayMember = "DisplayName";
            cgle_DrCode.Properties.DataSource = drs;
            cgle_DrCode.Closed += cgle_DrCode_Closed;
            cgle_DrCode.KeyDown += cgle_DrCode_KeyUp;

            tb_TransactionID.Focus();
        }

        private void cgle_DrCode_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                se_Quantity.Focus();
        }

        void cgle_DrCode_Closed(object sender, ClosedEventArgs e)
        {
            if (cgle_DrCode.EditValue != null)
            {
                se_Quantity.Focus();
            }
        }

        private void customGridLookUpEdit1_Enter(object sender, EventArgs e)
        {
            customGridLookUpEdit1.SelectAll();
        }


        /// <summary>
        /// </summary>
        /// <param name="sender"> </param>
        /// <param name="e"> </param>
        public void btn_Search_Click(object sender, EventArgs e)
        {
            patientActivation = DataRepository.PatientActivationProvider.GetByTransactionId(tb_TransactionID.Text);
            if (patientActivation != null)
            {
                if (patientActivation.IsComplete == false)
                    FillPatientInfo();
                else
                    MessageBox.Show(Resources.TransactionCompleted, "", MessageBoxButtons.OK);
            }
            else
            {
                MessageBox.Show(Resources.TransactionIDNotFound);
            }
        }

        private void FillPatientInfo()
        {
            lbl_PatientCode.Text = patientActivation.PatientCode;
            lbl_PatientName.Text = string.Format("{0} {1}", patientActivation.FirstName, patientActivation.LastName);
            DataRepository.PatientActivationProvider.DeepLoad(patientActivation);
            if (!String.IsNullOrEmpty(patientActivation.PatientCodeSource.BillingAddress))
                lbl_Address.Text = patientActivation.PatientCodeSource.BillingAddress;
            if (!String.IsNullOrEmpty(patientActivation.CompanyName))
                lbl_CompanyName.Text = patientActivation.CompanyName;
            lbl_MemberType.Text = patientActivation.MemberType;
            lbl_DateOfBirth.Text = patientActivation.DateOfBirth != null ? patientActivation.DateOfBirth.Value.ToString("yyyy") : " ";
            customGridLookUpEdit1.Focus();
            Text = lbl_PatientName.Text;
            RefreshProcedureGrid();
        }


        private void tb_PatientCode_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                btn_Search_Click(sender, e);
        }

        private void customGridLookUpEdit1_Closed(object sender, ClosedEventArgs e)
        {
            if (customGridLookUpEdit1.EditValue != null)
            {
                cgle_DrCode.Focus();
            }
        }


        private void CalculateTotal()
        {
            var subTotal = listDetails.Sum(detail => detail.UnitPrice);
            var coveredTotal = listDetails.Sum(detail => detail.CoveredPlan);
            var payableAmount = subTotal - coveredTotal;
            var vat = payableAmount * ServiceFacade.SettingsHelper.VATPercent / 100;
            var total = payableAmount + vat;
            string format = Resources.NumberFormat;
            lbl_SubTotal.Text = payableAmount.ToString(format);
            lbl_VAT.Text = vat.ToString(format);
            lbl_Total.Text = total.ToString(format);
        }


        private void btn_AddProcedure_Click(object sender, EventArgs e)
        {
            if (patientActivation == null)
            {
                MessageBox.Show(Resources.TransactionIdRequired);
                tb_TransactionID.Focus();
                return;
            }
            if (!customGridLookUpEdit1.EditValue.Equals(DBNull.Value) && (cgle_DrCode.EditValue.Equals(DBNull.Value)))
            {
                var objProcedure = (MedicalProcedure)customGridLookUpEdit1.EditValue;
                if (!objProcedure.AllowBlankDrCode)
                {
                    MessageBox.Show(Resources.DrCodeRequired);
                    cgle_DrCode.Focus();
                }
            }
            if (btn_AddProcedure.Text == "Update")
            {
                if (!customGridLookUpEdit1.EditValue.Equals(DBNull.Value))
                {
                    var objProcedure = (MedicalProcedure)customGridLookUpEdit1.EditValue;
                    editItem.ProcedureCode = objProcedure.ProcedureCode;
                    editItem.ProcedureDescription = objProcedure.ProcedureDescription;
                    var quantity = Int32.Parse(se_Quantity.Value.ToString("0"));
                    editItem.Quantity = quantity;
                    editItem.UnitPrice = objProcedure.UnitPrice;
                    var dr = (AppointmentDoctor)cgle_DrCode.EditValue;
                    if (dr != null)
                        editItem.DrCode = dr.Username;
                    editItem.CoveredPlan = CalculateCoverPlan(patientActivation.MemberType, editItem.ProcedureCode, editItem.UnitPrice, quantity);
                    editItem.TotalPay = editItem.UnitPrice * quantity - editItem.CoveredPlan;
                    btn_AddProcedure.Text = "Add";
                    btn_Clear.Text = "Clear";
                    customGridLookUpEdit1.EditValue = DBNull.Value;
                    cgle_DrCode.EditValue = DBNull.Value;
                    se_Quantity.Value = 1;
                    CalculateTotal();
                    gridControl1.RefreshDataSource();
                }
            }
            else
            {
                if (!customGridLookUpEdit1.EditValue.Equals(DBNull.Value))
                {
                    var objProcedure = (MedicalProcedure)customGridLookUpEdit1.EditValue;
                    var newItem = new InvoiceDetails { ProcedureCode = objProcedure.ProcedureCode };
                    var oldItem = listDetails.Find("ProcedureCode", newItem.ProcedureCode);
                    if (oldItem != null)
                    {
                        oldItem.Quantity += Int32.Parse(se_Quantity.Value.ToString("0"));
                        oldItem.CoveredPlan = CalculateCoverPlan(patientActivation.MemberType, oldItem.ProcedureCode,
                                                                 oldItem.UnitPrice, oldItem.Quantity);
                        oldItem.TotalPay = oldItem.UnitPrice * oldItem.Quantity - oldItem.CoveredPlan;
                        var dr = (AppointmentDoctor)cgle_DrCode.EditValue;
                        if (dr != null)
                            oldItem.DrCode = dr.Username;
                    }
                    else
                    {
                        newItem.ProcedureCode = objProcedure.ProcedureCode;
                        var quantity = Int32.Parse(se_Quantity.Value.ToString("0"));
                        newItem.Quantity = quantity;
                        if (objProcedure.AllowCustom)
                        {
                            var formMedicalProcedure = new FormMedicalProcedure();
                            formMedicalProcedure.ShowDialog();
                            newItem.ProcedureDescription = formMedicalProcedure.Description;
                            newItem.UnitPrice = formMedicalProcedure.Price;
                            newItem.CoveredPlan = 0;
                        }
                        else
                        {
                            newItem.ProcedureDescription = objProcedure.ProcedureDescription;
                            newItem.UnitPrice = objProcedure.UnitPrice;
                            newItem.CoveredPlan = CalculateCoverPlan(patientActivation.MemberType, newItem.ProcedureCode, newItem.UnitPrice, quantity);
                        }

                        var dr = (AppointmentDoctor)cgle_DrCode.EditValue;
                        if (dr != null)
                            newItem.DrCode = dr.Username;
                        newItem.TotalPay = newItem.UnitPrice * quantity - newItem.CoveredPlan;
                        newItem.InvoiceDetailId = "001";
                        listDetails.Add(newItem);
                    }
                }
                customGridLookUpEdit1.EditValue = DBNull.Value;
                cgle_DrCode.EditValue = DBNull.Value;
                se_Quantity.Value = 1;
                CalculateTotal();
                gridControl1.RefreshDataSource();
            }
            customGridLookUpEdit1.Focus();
        }

        private static decimal CalculateCoverPlan(string memberType, string procedureCode, decimal unitPrice, int quantity)
        {
            ProcedureDiscount discount = DataRepository.ProcedureDiscountProvider.GetByMemberTypeProcedureCode(memberType, procedureCode);
            if (discount != null)
                return (unitPrice * discount.DiscountPercent / 100) * quantity;
            return 0;
        }

        private void RefreshProcedureGrid()
        {
            foreach (var detail in listDetails)
            {
                detail.CoveredPlan = CalculateCoverPlan(patientActivation.MemberType, detail.ProcedureCode, detail.UnitPrice, detail.Quantity);
            }
            gridControl1.RefreshDataSource();
            CalculateTotal();
        }

        private void btnEdit_ButtonClick(object sender, ButtonPressedEventArgs e)
        {
            editItem = (InvoiceDetails)gridView1.GetRow(gridView1.FocusedRowHandle);
            se_Quantity.Value = editItem.Quantity;
            btn_AddProcedure.Text = "Update";
            btn_Clear.Text = "Cancel";
            customGridLookUpEdit1.EditValue = DataRepository.MedicalProcedureProvider.GetByProcedureCode(editItem.ProcedureCode);
            cgle_DrCode.EditValue = editItem.DrCode;
            customGridLookUpEdit1.Focus();
        }

        private void btnDelete_ButtonClick(object sender, ButtonPressedEventArgs e)
        {
            if (btn_AddProcedure.Text == "Update")
                customGridLookUpEdit1.Focus();
            else
            {
                var deleteItem = (InvoiceDetails)gridView1.GetRow(gridView1.FocusedRowHandle);
                listDetails.Remove(deleteItem);
                CalculateTotal();
            }
        }

        private void btn_Preview_Click(object sender, EventArgs e)
        {
            if (patientActivation != null)
            {
                string invoiceId;
                var Perfix = ServiceFacade.SettingsHelper.InvoicePrefix;
                int Count;
                var objInvoices =
                    DataRepository.InvoiceProvider.GetPaged("", "InvoiceID desc", 0, 1, out Count);
                CalculateTotal();
                if (Count == 0)
                    invoiceId = Perfix + "00001";
                else
                    invoiceId = Perfix +
                                     String.Format("{0:00000}",
                                                   int.Parse(
                                                       objInvoices[0].PrescriptionId.Substring(
                                                           objInvoices[0].PrescriptionId.Length - 3)) + 1);
                var insertInvoice = new Invoice
                                  {
                                      InvoiceId = invoiceId,
                                      InvoiceDate = DateTime.Now,
                                      TransactionId = patientActivation.TransactionId,
                                      FormNo = ServiceFacade.SettingsHelper.FormNo,
                                      Serial = ServiceFacade.SettingsHelper.InvoiceSerial,
                                      LocationCode = Program.GlobalUser.Location,
                                      LocationNumber = "00000",
                                      PatientCode = lbl_PatientCode.Text,
                                      FirstName = patientActivation.FirstName,
                                      LastName = patientActivation.LastName,
                                      Nationality = patientActivation.Nationality,
                                      DateOfBirth = patientActivation.DateOfBirth,
                                      Sex = patientActivation.Sex,
                                      CompanyCode = patientActivation.CompanyCode,
                                      CompanyName = patientActivation.CompanyName,
                                      Address = lbl_Address.Text,
                                      TaxCode = ServiceFacade.SettingsHelper.TaxCode,
                                      PaymentMode = "CASH",
                                      CreateUser = Program.GlobalUser.UserId,
                                      SubTotal = Decimal.Parse(lbl_SubTotal.Text),
                                      Vat = Decimal.Parse(lbl_VAT.Text),
                                      Total = Decimal.Parse(lbl_Total.Text),
                                      CreateDate = DateTime.Now
                                  };
                //if (AutoStock())
                //    if (StockOut(insertP))
                //    {
                //        insertP.PrescriptionDetailCollection = listDetails;
                //    PrintDeliveryNote(insertP);
                //    var formPrescriptionLabel = new FormPrescriptionLabel();
                //    formPrescriptionLabel.LoadDefault(insertP.PrescriptionId);
                //    formPrescriptionLabel.Show();
                //    LoadDefault();
                //    FillBlankPatient();
                //    patientActivation = null;
                //}
            }
            else
            {
                MessageBox.Show(Resources.TransactionIdRequired);
                tb_TransactionID.Focus();
            }
        }

        // Stock Out
        //public bool StockOut(Prescription insertP)
        //{
        //    TransactionManager transaction = DataRepository.Provider.CreateTransaction();
        //    transaction.BeginTransaction();
        //    try
        //    {
        //        DataRepository.PrescriptionProvider.Insert(transaction, insertP);
        //        foreach (PrescriptionDetail detail in listDetails)
        //        {
        //            detail.PrescriptionId = insertP.PrescriptionId;
        //            Entities.TList<Stock> items = DataRepository.StockProvider.GetItems(transaction, detail.DrugId);
        //            DrugDispo drug = DataRepository.DrugDispoProvider.GetByDrugId(detail.DrugId);
        //            int quantity = detail.Quantity;
        //            int oldQuantity = detail.Quantity;
        //            int Count = 0;
        //            while (quantity > 0)
        //            {
        //                detail.ExpDate = items[Count].ExpDate;
        //                detail.BatchLot = items[Count].BatchLot;
        //                detail.IsControlDrug = drug.IsControlDrug;
        //                if (items[Count].Quantity > quantity)
        //                {
        //                    items[Count].Quantity -= quantity;
        //                    detail.Quantity = quantity;
        //                    detail.CoveredPlan = CalculateCoverPlan(patientActivation.MemberType, detail.DrugId, detail.UnitPrice,
        //                                                            detail.Quantity);
        //                    DataRepository.PrescriptionDetailProvider.Insert(transaction, detail);
        //                    DataRepository.StockProvider.Update(transaction, items[Count]);
        //                    quantity = 0;
        //                }
        //                else
        //                {
        //                    quantity -= items[Count].Quantity;
        //                    detail.Quantity = items[Count].Quantity;
        //                    detail.CoveredPlan = CalculateCoverPlan(patientActivation.MemberType, detail.DrugId, detail.UnitPrice,
        //                                                            detail.Quantity);
        //                    DataRepository.PrescriptionDetailProvider.Insert(transaction, detail);
        //                    DataRepository.StockProvider.Delete(transaction, items[Count++]);
        //                }
        //            }
        //            detail.Quantity = oldQuantity;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        transaction.Rollback();
        //        MessageBox.Show("Error " + ex.Message);
        //        return false;
        //    }
        //    transaction.Commit();
        //    return true;
        //}


        private void PrintDeliveryNote(Prescription printP)
        {
            //Utilities.CreateDBF(printP);
            //bool canPrint = true;
            ////bool printControlDrug = Utilities.PreviewDeliveryNote(printP, reportViewer1,
            ////                                                      ServiceFacade.SettingsHelper.CustomerCopy, false, "",
            ////                                                      ref canPrint);
            ////if (canPrint)
            ////{
            //var printDoc = new ReportPrintDocument(reportViewer1.LocalReport);
            //printDoc.Print();
            //Utilities.PreviewDeliveryNote(printP, reportViewer1, ServiceFacade.SettingsHelper.CustomerCopy, false, "",
            //                              ref canPrint);
            //printDoc = new ReportPrintDocument(reportViewer1.LocalReport);
            //printDoc.Print();
            //Utilities.PreviewDeliveryNote(printP, reportViewer1, ServiceFacade.SettingsHelper.FileCopy, false,
            //                              "", ref canPrint);
            //printDoc = new ReportPrintDocument(reportViewer1.LocalReport);
            //printDoc.Print();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="patientCode"></param>
        /// <param name="patientName"></param>
        /// <param name="dateOfBirth"></param>
        /// <param name="address"></param>
        public void FillBlankPatient()
        {
            tb_TransactionID.Text = "";
            lbl_PatientCode.Text = " ";
            lbl_PatientName.Text = " ";
            lbl_Address.Text = " ";
            lbl_DateOfBirth.Text = " ";
            lbl_CompanyName.Text = " ";
            lbl_MemberType.Text = " ";
            CalculateTotal();
        }

        private void btn_Reset_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show(Resources.ResetForm, "", MessageBoxButtons.OKCancel) ==
                DialogResult.OK)
            {
                LoadDefault();
                CalculateTotal();
                FillBlankPatient();
                tb_TransactionID.Text = "";
            }
        }

        private void gridView1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
                btnDelete_ButtonClick(sender, null);
            else if (e.KeyCode == Keys.Insert)
            {
                btnEdit_ButtonClick(sender, null);
                customGridLookUpEdit1.Focus();
            }
        }

        private void btn_Clear_Click(object sender, EventArgs e)
        {
            btn_Clear.Text = "Clear";
            btn_AddProcedure.Text = "Add";
            customGridLookUpEdit1.EditValue = DBNull.Value;
            cgle_DrCode.EditValue = DBNull.Value;
            se_Quantity.Value = 1;
            customGridLookUpEdit1.Focus();
        }

    }
}